package org.alwayssuper.web.config;

import org.alwayssuper.protostar.SchemaManager;
import org.alwayssuper.commons.spring.SSEService;
import org.alwayssuper.netmc.NettyConfig;
import org.alwayssuper.netmc.Server;
import org.alwayssuper.netmc.codec.Delimiter;
import org.alwayssuper.netmc.core.HandlerMapping;
import org.alwayssuper.netmc.core.SpringHandlerMapping;
import org.alwayssuper.netmc.session.SessionListener;
import org.alwayssuper.netmc.session.SessionManager;
import org.alwayssuper.protocol.codec.GBTMessageAdapter;
import org.alwayssuper.protocol.codec.GBTMessageDecoder;
import org.alwayssuper.protocol.codec.GBTMessageEncoder;
import org.alwayssuper.web.endpoint.GBTHandlerInterceptor;
import org.alwayssuper.web.endpoint.GBTMessagePushAdapter;
import org.alwayssuper.web.model.enums.SessionKey;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

/**
 * @author alwaysSuper
 */
@Order(Integer.MIN_VALUE)
@Configuration
@ConditionalOnProperty(value = "gbt-server.gbt32960.enabled", havingValue = "true", matchIfMissing = true)
public class GBTConfig {

    @ConditionalOnProperty(value = "gbt-server.gbt32960.tcp-port")
    @Bean(initMethod = "start", destroyMethod = "stop")
    public Server gbt32960TCPServer(GBTMessageAdapter messageAdapter,
                                 HandlerMapping handlerMapping,
                                 GBTHandlerInterceptor handlerInterceptor,
                                 SessionManager sessionManager,
                                 GBTProperties jtProperties) {
        return NettyConfig.custom()
                .setIdleStateTime(jtProperties.getIdleTimeout(), 0, 0)
                .setPort(jtProperties.getTcpPort())
                //标识位[4] + 消息头[22] + 消息体[0—65531]  + 校验码[1]
                .setMaxFrameLength(2 + 22 + 65531 + 1 )
                //#2323为2016版 #2424为2025版
                .setDelimiters(new Delimiter(new byte[]{0x23,0x23}, false),new Delimiter(new byte[]{0x24,0x24}, false))
                .setBodyLengthFieldStartPos(20)
                .setBodyLengthFieldEndPos(22)
                .setHeaderLength(22)
                .setDecoder(messageAdapter)
                .setEncoder(messageAdapter)
                .setHandlerMapping(handlerMapping)
                .setHandlerInterceptor(handlerInterceptor)
                .setSessionManager(sessionManager)
                .setName("32960-TCP")
                .build();
    }
    @Bean
    public GBTMessageAdapter jtMessageAdapter(SchemaManager schemaManager, SSEService sseService) {
        GBTMessageEncoder messageEncoder = new GBTMessageEncoder(schemaManager);
        GBTMessageDecoder messageDecoder = new GBTMessageDecoder(schemaManager);
        return new GBTMessagePushAdapter(messageEncoder, messageDecoder, sseService);
    }

    @Bean
    public HandlerMapping handlerMapping() {
        return new SpringHandlerMapping();
    }

    @Bean
    public SessionManager sessionManager(SessionListener sessionListener) {
        return new SessionManager(SessionKey.class, sessionListener);
    }

    @Bean
    public SchemaManager schemonaManager(GBTProperties gbtProperties) {
        return new SchemaManager(gbtProperties.getMessagePackage());
    }

    @Bean
    public GBTMessageDecoder gbtMessageDecoder(SchemaManager schemaManager) {
        return new GBTMessageDecoder(schemaManager);
    }
}
